/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.buss.core.utils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringEscapeUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * 
 * @author Administrator
 */
public class StringUtil {

    static URLCodec urlCodec = new URLCodec();
    public static final char[] HexDigits = {'0', '1', '2', '3', '4', '5', '6',
        '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    public static Pattern patternHtmlTag = Pattern.compile("<[^<>]+>", 32);
    /**
     * 将字符串进行MD5加密
     *
     * @param src
     * @return
     */
//	public static byte[] md5(String src) {
//		try {
//			MessageDigest md5 = MessageDigest.getInstance("MD5");
//			byte[] md = md5.digest(src.getBytes());
//			return md;
//		} catch (Exception e) {
//		}
//		return null;
//	}
//
    public static byte[] md5(byte[] src) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] md = md5.digest(src);
            return md;
        } catch (Exception e) {
        }
        return null;
    }

    public static String md5Hex(String src) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] md = md5.digest(src.getBytes());
            return hexEncode(md);
        } catch (Exception e) {
        }
        return null;
    }

    public static String md5Base64(String src) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            return base64Encode(md5.digest(src.getBytes()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String md5Base64FromHex(String md5str) {
        char[] cs = md5str.toCharArray();
        byte[] bs = new byte[16];
        for (int i = 0; i < bs.length; ++i) {
            char c1 = cs[(i * 2)];
            char c2 = cs[(i * 2 + 1)];
            byte m1 = 0;
            byte m2 = 0;
            for (byte k = 0; k < 16; k = (byte) (k + 1)) {
                if (HexDigits[k] == c1) {
                    m1 = k;
                }
                if (HexDigits[k] == c2) {
                    m2 = k;
                }
            }
            bs[i] = (byte) (m1 << 4 | 0 + m2);
        }
        String newstr = base64Encode(bs);
        return newstr;
    }

    public static String md5HexFromBase64(String base64str) {
        return hexEncode(base64Decode(base64str));
    }

    public static String hexEncode(byte[] bs) {
        return new String(new Hex().encode(bs));
    }

    public static byte[] hexDecode(String str) {
        try {
            if (str.endsWith("\n")) {
                str = str.substring(0, str.length() - 1);
            }
            char[] cs = str.toCharArray();
            return Hex.decodeHex(cs);
        } catch (DecoderException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String byteToBin(byte[] bs) {
        char[] cs = new char[bs.length * 9];
        for (int i = 0; i < bs.length; i++) {
            byte b = bs[i];
            int j = i * 9;
            cs[j] = (((b >>> 7 & 0x1) == 1) ? 49 : '0');
            cs[(j + 1)] = (((b >>> 6 & 0x1) == 1) ? 49 : '0');
            cs[(j + 2)] = (((b >>> 5 & 0x1) == 1) ? 49 : '0');
            cs[(j + 3)] = (((b >>> 4 & 0x1) == 1) ? 49 : '0');
            cs[(j + 4)] = (((b >>> 3 & 0x1) == 1) ? 49 : '0');
            cs[(j + 5)] = (((b >>> 2 & 0x1) == 1) ? 49 : '0');
            cs[(j + 6)] = (((b >>> 1 & 0x1) == 1) ? 49 : '0');
            cs[(j + 7)] = (((b & 0x1) == 1) ? 49 : '0');
            cs[(j + 8)] = ',';
        }
        return new String(cs);
    }

    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; ++i) {
            resultSb.append(byteToNumString(b[i]));
            resultSb.append(" ");
        }
        return resultSb.toString();
    }

    private static String byteToNumString(byte b) {
        int _b = b;
        if (b < 0) {
            _b = 256 + _b;
        }
        return String.valueOf(_b);
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return String.valueOf(HexDigits[d1]) + String.valueOf(HexDigits[d2]);
    }

    public static boolean isUTF8(byte[] bs) {
        if (hexEncode(ArrayUtils.subarray(bs, 0, 3)).equals("efbbbf")) {
            return true;
        }
        int lLen = bs.length;
        for (int i = 0; i < lLen;) {
            byte b = bs[(i++)];
            if (b >= 0) {
                continue;
            }
            if ((b < -64) || (b > -3)) {
                return false;
            }
            int c = (b > -32) ? 2 : (b > -16) ? 3 : (b > -8) ? 4 : (b > -4) ? 5
                    : 1;
            if (i + c > lLen) {
                return false;
            }
            for (int j = 0; j < c; ++i) {
                if (bs[i] >= -64) {
                    return false;
                }
                ++j;
            }

        }

        return true;
    }

    public static String base64Encode(byte[] b) {
        if (b == null) {
            return null;
        }
        return new BASE64Encoder().encode(b);
    }

    public static byte[] base64Decode(String s) {
        if (s != null) {
            BASE64Decoder decoder = new BASE64Decoder();
            try {
                return decoder.decodeBuffer(s);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static String replaceEx(String str, String subStr, String reStr) {
        if (str == null) {
            return null;
        }
        if ((subStr == null) || (subStr.equals(""))
                || (subStr.length() > str.length()) || (reStr == null)) {
            return str;
        }
        StringBuffer sb = new StringBuffer();
        String tmp = str;
        int index = -1;
        while (true) {
            index = tmp.indexOf(subStr);
            if (index < 0) {
                break;
            }
            sb.append(tmp.substring(0, index));
            sb.append(reStr);
            tmp = tmp.substring(index + subStr.length());
        }
        sb.append(tmp);
        return sb.toString();
    }

    public static String javaEncode(String txt) {
        if ((txt == null) || (txt.length() == 0)) {
            return txt;
        }
        txt = replaceEx(txt, "\\", "\\\\");
        txt = replaceEx(txt, "\r\n", "\n");
        txt = replaceEx(txt, "\n", "\\n");
        txt = replaceEx(txt, "\"", "\\\"");
        txt = replaceEx(txt, "'", "\\'");
        return txt;
    }

    public static String javaDecode(String txt) {
        if ((txt == null) || (txt.length() == 0)) {
            return txt;
        }
        txt = replaceEx(txt, "\\\\", "\\");
        txt = replaceEx(txt, "\\n", "\n");
        txt = replaceEx(txt, "\\r", "\r");
        txt = replaceEx(txt, "\\\"", "\"");
        txt = replaceEx(txt, "\\'", "'");
        return txt;
    }

    public static String[] splitEx(String str, String spilter) {
        if (str == null) {
            return null;
        }
        if ((spilter == null) || (spilter.equals(""))
                || (str.length() < spilter.length())) {
            String[] t = {str};
            return t;
        }
        ArrayList al = new ArrayList();
        char[] cs = str.toCharArray();
        char[] ss = spilter.toCharArray();
        int length = spilter.length();
        int lastIndex = 0;
        for (int i = 0; i <= str.length() - length;) {
            boolean notSuit = false;
            for (int j = 0; i < length; ++j) {
                if (cs[(i + j)] != ss[j]) {
                    notSuit = true;
                    break;
                }
            }
            if (!(notSuit)) {
                al.add(str.substring(lastIndex, i));
                i += length;
                lastIndex = i;
            } else {
                ++i;
            }
        }
        if (lastIndex <= str.length()) {
            al.add(str.substring(lastIndex, str.length()));
        }
        String[] t = new String[al.size()];
        for (int i = 0; i < al.size(); ++i) {
            t[i] = ((String) al.get(i));
        }
        return t;
    }

    public static String substring(String text, int length) {
        return text.substring(0, length);
    }

    public static String replaceAllIgnoreCase(String source, String oldstring,
            String newstring) {
        Pattern p = Pattern.compile(oldstring, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(source);
        return m.replaceAll(newstring);
    }

    public static String urlEncode(String str, String charSet) {
        try {
            return urlCodec.encode(str, charSet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String urlDecode(String str, String charSet) {
        try {
            return urlCodec.decode(str, charSet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String htmlEncode(String txt) {
        return StringEscapeUtils.escapeHtml(txt);
    }

    public static String htmlDecode(String txt) {
        txt = replaceEx(txt, "&#8226;", "·");
        return StringEscapeUtils.unescapeHtml(txt);
    }

    public static String quotEncode(String txt) {
        if ((txt == null) || (txt.length() == 0)) {
            return txt;
        }
        txt = replaceEx(txt, "&", "&amp;");
        txt = replaceEx(txt, "\"", "&quot;");
        return txt;
    }

    public static String quotDecode(String txt) {
        if ((txt == null) || (txt.length() == 0)) {
            return txt;
        }
        txt = replaceEx(txt, "&quot;", "\"");
        txt = replaceEx(txt, "&amp;", "&");
        return txt;
    }

    public static String escape(String src) {
        StringBuffer sb = new StringBuffer();
        sb.ensureCapacity(src.length() * 6);
        for (int i = 0; i < src.length(); ++i) {
            char j = src.charAt(i);
            if ((Character.isDigit(j)) || (Character.isLowerCase(j))
                    || (Character.isUpperCase(j))) {
                sb.append(j);
            } else if (j < 256) {
                sb.append("%");
                if (j < '\16') {
                    sb.append("0");
                }
                sb.append(Integer.toString(j, 16));
            } else {
                sb.append("%u");
                sb.append(Integer.toString(j, 16));
            }
        }
        return sb.toString();
    }

    public static String unEscape(String src) {
        StringBuffer sb = new StringBuffer();
        sb.ensureCapacity(src.length());
        int lastPos = 0;
        int pos = 0;

        while (lastPos < src.length()) {
            pos = src.indexOf("%", lastPos);
            if (pos == lastPos) {
                char ch;
                if (src.charAt(pos + 1) == 'u') {
                    ch = (char) Integer.parseInt(src.substring(pos + 2, pos + 6), 16);
                    sb.append(ch);
                    lastPos = pos + 6;
                } else {
                    ch = (char) Integer.parseInt(src.substring(pos + 1, pos + 3), 16);
                    sb.append(ch);
                    lastPos = pos + 3;
                }
            } else if (pos == -1) {
                sb.append(src.substring(lastPos));
                lastPos = src.length();
            } else {
                sb.append(src.substring(lastPos, pos));
                lastPos = pos;
            }
        }

        return sb.toString();
    }

    public static String getChineseFullSpell(String cnStr) {
        if ((cnStr == null) || ("".equals(cnStr.trim()))) {
            return cnStr;
        }
        return ChineseSpelling.getPinYin(cnStr);
    }

    public static String getChineseFamilyName(String cnStr) {
        if ((cnStr == null) || ("".equals(cnStr.trim()))) {
            return cnStr;
        }
        return ChineseSpelling.getPinYinHeadCharForOne(cnStr);
    }

    public static String getChineseFirstAlpha(String cnStr) {
        if ((cnStr == null) || ("".equals(cnStr.trim()))) {
            return cnStr;
        }
        return ChineseSpelling.getPinYinHeadChar(cnStr);
    }

    public static boolean isEmpty(String str) {
        return ((str == null) || str.length() == 0);
    }

    public static boolean isNotEmpty(String str) {
        return (!isEmpty(str));
    }

    /**
     * 将数值型字符串转换成中国大写货币<Br>
     * 从个位开始转换
     *
     * @param value
     * @param valueTitle
     * @return
     * @throws DataIllegalException
     */
    public final static String toZhCNCurrencyUpperCase(String value,
            String valueTitle) {

        BigDecimal bigdMoneyNumber = new BigDecimal(value);
        if (bigdMoneyNumber.compareTo(new BigDecimal(1000000000000L)) > -1) {// 只能是小于1万亿
            Logger1.error("[" + valueTitle + "] 赋值错误[最大值：999999999999.99]",
                    StringUtil.class);
        }
        // 中文金额单位数组
        String[] straChineseUnit = {"分", "角", "圆", "拾", "佰", "仟", "万", "拾",
            "佰", "仟", "亿", "拾", "佰", "仟"};
        // 中文数字字符数组
        String[] straChineseNumber = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒",
            "捌", "玖"};
        String strChineseCurrency = "";
        // 零数位标记
        boolean bZero = true;
        // 中文金额单位下标:从个位开始转换
        int ChineseUnitIndex = 0;
        if (bigdMoneyNumber.intValue() == 0) {
            return "零圆整";
        }
        // 处理小数部分，四舍五入
        double doubMoneyNumber = Math.round(bigdMoneyNumber.doubleValue() * 100);
        // 是否负数
        boolean bNegative = doubMoneyNumber < 0;
        // 取绝对值
        doubMoneyNumber = Math.abs(doubMoneyNumber);
        // 循环处理转换操作
        while (doubMoneyNumber > 0) {
            // 整的处理(无小数位)
            if (ChineseUnitIndex == 2 && strChineseCurrency.length() == 0) {
                strChineseCurrency = strChineseCurrency + "整";
            }
            // 非零数位的处理
            double x = doubMoneyNumber % 10; // 此句必须有，否则，在(int)x时会有问题，如(int)999999999999.99%10其结果不是9而是7
            if (x > 0) {
                strChineseCurrency = straChineseNumber[(int) x]
                        + straChineseUnit[ChineseUnitIndex]
                        + strChineseCurrency;
                bZero = false;
            } // 零数位的处理
            else {
                // 元的处理(个位)
                if (ChineseUnitIndex == 2) {
                    // 段中有数字
                    if (doubMoneyNumber > 0) {
                        strChineseCurrency = straChineseUnit[ChineseUnitIndex]
                                + strChineseCurrency;
                        bZero = true;
                    }
                } // 万、亿数位的处理
                else if (ChineseUnitIndex == 6 || ChineseUnitIndex == 10) {
                    // 段中有数字
                    if (doubMoneyNumber % 1000 > 0) {
                        strChineseCurrency = straChineseUnit[ChineseUnitIndex]
                                + strChineseCurrency;
                    }
                }
                // 前一数位非零的处理
                if (!bZero) {
                    strChineseCurrency = straChineseNumber[0]
                            + strChineseCurrency;
                }
                bZero = true;
            }
            doubMoneyNumber = Math.floor(doubMoneyNumber / 10);
            ChineseUnitIndex++;
        }
        // 负数的处理
        if (bNegative) {
            strChineseCurrency = "负" + strChineseCurrency;
        }
        return strChineseCurrency;
    }

    /**
     * 将字符串数字转换为字符串格式
     * @param args
     * @param split
     * @return
     */
    public static String join(String[] args, String split) {
    	if(args == null || args.length == 0){
    		return "";
    	}
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < args.length; i++) {
            sb.append(args[i]);
            if (i < args.length - 1) {
                sb.append(split);
            }
        }
        return sb.toString();
    }

    public static String clearHtmlTag(String html) {
        String text = patternHtmlTag.matcher(html).replaceAll("");
        if (isEmpty(text)) {
            return "";
        }
        text = htmlDecode(html);
        return text.replaceAll("[\\s　]{2,}", " ");
    }

    /**
     * 将一个long型数组转换成字符串。转换后的:(1,2,3)形式
     * @param ids
     * @return
     */
    public static String getIds(long[] ids) {
        StringBuffer idsStr = new StringBuffer("");
        if (ids != null && ids.length > 0) {
            for (long id : ids) {
                idsStr.append(",");
                idsStr.append(id);
            }
        }
        return "(" + idsStr.deleteCharAt(0).append(")").toString();
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
     /*   String aaa = getChineseFirstAlpha("中华人民");
        System.out.println(aaa);*/
    }
}
